﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Simhopp.Common
{
    /// <summary>
    /// The Credentials class provides the basic credentials of a person.
    /// </summary>
    [Serializable]
    public class Credentials : ISerializable, IDatabaseObject
    {
        #region FIELD REGION
        private int id;
        private String name;
        private Genders gender;
        private int age;
        private String nationality;
        private String socialSecurityNumber;
        #endregion
        #region CONSTRUCTOR REGION
        /// <summary>
        /// Default constructor
        /// </summary>
        public Credentials()
        {
            id = -1;
            name = "";
            Gender = Genders.Male;
            age = 0;
            nationality = "";
            socialSecurityNumber = "";
        }
        #endregion
        #region PROPERTY REGION
        /// <summary>
        /// Property Id gets or sets the id field.
        /// </summary>
        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        /// <summary>
        /// Property Name gets or sets the name field.
        /// </summary>
        public String Name
        {
            get { return name; }
            set { name = value; }
        }
        /// <summary>
        /// Property Gender gets or sets the gender field.
        /// </summary>
        public Genders Gender
        {
            get { return gender; }
            set { gender = value; }
        }
        /// <summary>
        /// Property Age gets or sets the age field.
        /// </summary>
        public int Age 
        {
            get { return age; }
            set { age = value; }
        }
        /// <summary>
        /// Property Nationality gets or sets the nationality field.
        /// </summary>
        public String Nationality 
        {
            get { return nationality; }
            set { nationality = value; }
        }
        /// <summary>
        /// Property SocialSecurityNumber gets or sets the social security number.
        /// </summary>
        public String SocialSecurityNumber
        {
            get { return socialSecurityNumber; }
            set { socialSecurityNumber = value; }
        }
        #endregion
        #region METHOD REGION
        /// <summary>
        /// Checks if two instances of the object are identical
        /// </summary>
        /// <param name="obj">The object to compare with</param>
        /// <returns>True/False</returns>
        public override bool Equals(object obj)
        {
            return ((Credentials)obj).Id == this.Id;
        }
        /// <summary>
        /// Used in addition to Equals method
        /// </summary>
        /// <returns>A unique id</returns>
        public override int GetHashCode()
        {
            return id;
        }

        #endregion
        #region DATABASE REGION

        /// <summary>
        /// Creates a dictionary from the object where member field names are mapped to their corresponding values
        /// </summary>
        /// <returns>A dictionary</returns>
        public Dictionary<String, Object> GetDictionary()
        {
            try
            {
                var dictionary = new Dictionary<String, Object>();
                dictionary.Add("Id", this.Id.ToString());
                dictionary.Add("Name", this.Name);
                dictionary.Add("Gender", ((int)this.Gender).ToString());
                dictionary.Add("Age", this.Age.ToString());
                dictionary.Add("Nationality", this.Nationality);
                dictionary.Add("SocialSecurityNumber", this.SocialSecurityNumber);

                return dictionary;
            }
            catch (Exception e)
            {
                MyLogger.Error("Failed to create dictionary from Credentials object - " + e.Message);
                return null;
            }
        }

        /// <summary>
        /// Creates a Credentials-object from a passed dictionary
        /// </summary>
        /// <param name="data">A dictionary where database field names are mapped to their corresponding values</param>
        /// <returns>A Credentials object</returns>
        public static Credentials GetFromDictionary(Dictionary<String, Object> data)
        {
            var credentials = new Credentials();
            try
            {
                credentials.Id = (int) data["Id"];
            }
            catch (Exception e)
            {
                credentials.Id = -1;
            }
            try
            {
                credentials.Name = ((String) data["Name"]).Trim();
            }
            catch (Exception e)
            {
                credentials.Name = "";
            }
            try
            {
                credentials.Gender = (Genders) data["Gender"];
            }
            catch (Exception e)
            {
                credentials.Gender = Genders.Female;
            }
            try
            {
                credentials.Age = (int) data["Age"];
            }
            catch (Exception e)
            {
                credentials.Age = 0;
            }
            try
            {
                credentials.Nationality = ((String) data["Nationality"]).Trim();
            }
            catch (Exception e)
            {
                credentials.Nationality = "";
            }
            try
            {
                credentials.SocialSecurityNumber = ((String) data["SocialSecurityNumber"]).Trim();
            }
            catch (Exception e)
            {
                credentials.SocialSecurityNumber = "";
            }
            return credentials;
        }

        /// <summary>
        /// Returns the name of the Id field used in the corresponding database-table
        /// </summary>
        /// <returns></returns>
        public String GetIdFieldName()
        {
            return "Id";
        }

        /// <summary>
        /// Returns the name of the database table containing this type
        /// </summary>
        /// <returns></returns>
        public String GetTableName()
        {
            return "Credentials";
        }

        #endregion
        #region SERIALIZE/DESERIALIZE REGION
        /// <summary>
        /// Adds the class specific information used in the serialization of an object.
        /// </summary>
        /// <param name="info">The class specific information.</param>
        /// <param name="context">Describes the source and destination of a given serialized stream.</param>
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Id", id, typeof(int));
            info.AddValue("Name", name, typeof(String));
            info.AddValue("Gender", gender, typeof(Genders));
            info.AddValue("Age", age, typeof(int));
            info.AddValue("Nationality", nationality, typeof(String));
            info.AddValue("SocialSecurityNumber", socialSecurityNumber, typeof(String));
        }
        /// <summary>
        /// Constructor used in the deserialization of an object.
        /// </summary>
        /// <param name="info">The class specific information.</param>
        /// <param name="context">Describes the source and destination of a given serialized stream.</param>
        protected Credentials(SerializationInfo info, StreamingContext context)
        {
            id = (int)info.GetValue("Id", typeof(int));
            name = (String)info.GetValue("Name", typeof(String));
            gender = (Genders)info.GetValue("Gender", typeof(Genders));
            age = (int)info.GetValue("Age", typeof(int));
            nationality = (String)info.GetValue("Nationality", typeof(String));
            socialSecurityNumber = (String)info.GetValue("SocialSecurityNumber", typeof(String));
        }
        #endregion
    }
}
